package com.mephi.oshs.model.interpreter.example;

import com.mephi.oshs.model.interpreter.api.IContext;
import com.mephi.oshs.model.interpreter.api.IExpression;
import com.mephi.oshs.model.interpreter.impl.ComparisonExpression;
import com.mephi.oshs.model.interpreter.impl.TestContext;

import static com.mephi.oshs.model.interpreter.ExpressionFactory.*;

public class RunInterpreterPattern {
    public static void main(String[] arguments) {
        final ContactList candidates = makeContactList();
        final IContext ctx = new TestContext();
        final Contact testContact = new ContactImpl();

        System.out.println("Example for the Interpreter pattern");
        System.out.println("In this demonstration, the syntax defined");
        System.out.println(" by the Interpreter can be used to search");
        System.out.println(" among a collection of Contacts, returning");
        System.out.println(" the subset that match the given search criteria.");
        System.out.println();
        System.out.println("Contents of the ContactList:");
        System.out.println(candidates);

        System.out.println("-------------------------------------------------");

        // Используем геттер на контакте для получения фамилии.
        final IExpression varLName = getVariableExpression(testContact, "getLastName");

        // Константа - буква u.
        final IExpression constLName = getConstantExpression("u");

        // Смотрим содержится ли в результате первого выражения результат второго выражения:
        // в фамилии контакта буква u.
        final IExpression eqLName = getContainsExpression(varLName, constLName);

        System.out.println("Contents of the search on ContactList:");
        System.out.println("(search was contains 'u' in Last Name)");

        Object result = candidates.getContactsMatchingExpression(eqLName, ctx, testContact);
        System.out.println(result);

        System.out.println("-------------------------------------------------");

        // Используем геттер на контакте для получения звания.
        final IExpression varTitle = getVariableExpression(testContact, "getTitle");

        // Константа - буквы LT.
        final IExpression constTitle = getConstantExpression("LT");

        // Смотрим равны ли результат первого выражения и результат второго выражения:
        // звание контакта и буквы LT.
        final IExpression eqTitle = getEqualsExpression(varTitle, constTitle);

        System.out.println("Contents of the search on ContactList:");
        System.out.println("(search was all LT personnel)");

        result = candidates.getContactsMatchingExpression(eqTitle, ctx, testContact);
        System.out.println(result);

        System.out.println("-------------------------------------------------");

        // Используем геттер на контакте для получения фамилии.
        final IExpression varLastName = getVariableExpression(testContact, "getLastName");

        // Константа - буква S.
        final IExpression constLastName = getConstantExpression("S");

        // Смотрим содержится ли в результате первого выражения результат второго выражения:
        // в фамилии контакта буква S.
        final IExpression cLName = getContainsExpression(varLastName, constLastName);

        // Логическое "И" для двух выражений:
        // (равно ли звание контакта буквам LT) И (содержится ли в фамилии контакта буква S).
        final IExpression andExpr = getAndExpression((ComparisonExpression) eqTitle, (ComparisonExpression) cLName);

        System.out.println("Contents of the search on ContactList:");
        System.out.println("(search was all LT personnel with 'S' in Last Name)");
        result = candidates.getContactsMatchingExpression(andExpr, ctx, testContact);
        System.out.println(result);

        System.out.println("-------------------------------------------------");
    }

    private static ContactList makeContactList() {
        final ContactList returnList = new ContactList();
        returnList.addContact(new ContactImpl("James", "Kirk", "Captain", "USS Enterprise"));
        returnList.addContact(new ContactImpl("Mr.", "Spock", "Science Officer", "USS Enterprise"));
        returnList.addContact(new ContactImpl("LT", "Uhura", "LT", "USS Enterprise"));
        returnList.addContact(new ContactImpl("LT", "Sulu", "LT", "USS Enterprise"));
        returnList.addContact(new ContactImpl("Ensign", "Checkov", "Ensign", "USS Enterprise"));
        returnList.addContact(new ContactImpl("Dr.", "McCoy", "Ship's Doctor", "USS Enterprise"));
        returnList.addContact(new ContactImpl("Montgomery", "Scott", "LT", "USS Enterprise"));
        return returnList;
    }
}